package com.ransj.iphone.utils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;

import com.ransj.iphone.IConfig;

import android.os.Environment;
import android.util.Log;

/**
 * 
 * @author ranshengju
 * 
 */
public class ILog {
	private static final String LOG_LEVEL_V = "v";
	private static final String LOG_LEVEL_D = "d";
	private static final String LOG_LEVEL_I = "i";
	private static final String LOG_LEVEL_W = "w";
	private static final String LOG_LEVEL_E = "e";
	private static ILog mInstance = new ILog();
	private HashMap<String, BufferedWriter> mWriterMap;

	private ILog() {
		mWriterMap = new HashMap<String, BufferedWriter>();
	}

	public static ILog getInstance() {
		return mInstance;
	}

	public void i(String TAG, String str) {
		if(IConfig.DEBUG){
			printf(LOG_LEVEL_I, TAG, str);
			Log.i(TAG, str);
		}
	}

	public void d(String TAG, String str) {
		if(IConfig.DEBUG){
			printf(LOG_LEVEL_D, TAG, str);
			Log.d(TAG, str);
		}
	}

	public void v(String TAG, String str) {
		if(IConfig.DEBUG){
			printf(LOG_LEVEL_V, TAG, str);
			Log.v(TAG, str);
		}
	}

	public void w(String TAG, String str) {
		if(IConfig.DEBUG){
			printf(LOG_LEVEL_W, TAG, str);
			Log.w(TAG, str);
		}
	}

	public void e(String TAG, Exception e) {
		if(IConfig.DEBUG){
			e.printStackTrace();
			try {
				BufferedWriter writer = getBufferWriter(LOG_LEVEL_E);
				writer.append("---------->");
				writer.append(TAG);
				writer.append(',');
				writer.append(currTime());
				writer.append("<----------");
				writer.append('\n');
				writer.append(e.getMessage());
				writer.append('\n');
				StackTraceElement[] traces = e.getStackTrace();
				int length = traces.length;
				for (int i = 0; i < length; i++) {
					StackTraceElement element = traces[i];
					writer.append(element.toString());
					writer.append('\n');
				}
				writer.append("---------->");
				writer.append("END");
				writer.append("<----------");
				writer.flush();
			} catch (Exception e1) {
				e1.printStackTrace();
			}
		}
	}

	private void printf(String level, String TAG, String str) {
		try {
			BufferedWriter writer = getBufferWriter(level);
			writer.append(currTime());
			writer.append('\t');
			writer.append(TAG);
			writer.append('\t');
			writer.append(str);
			writer.append('\n');
			writer.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private BufferedWriter getBufferWriter(String level) throws IOException {
		if (Environment.getExternalStorageState().equalsIgnoreCase(
				Environment.MEDIA_MOUNTED)) {
			if (mWriterMap.containsKey(level)) {
				return mWriterMap.get(level);
			}
			String path = Environment.getExternalStorageDirectory()
					.getAbsolutePath()
					+ File.separatorChar
					+ IConfig.LOG_NAME
					+ level + ".txt";
			File log = new File(path);
			File parent = log.getParentFile();
			if (!parent.exists()) {
				parent.mkdirs();
			}
			if (!log.exists()) {
				log.createNewFile();
			}
			BufferedWriter writer = new BufferedWriter(
					new FileWriter(log, true));
			mWriterMap.put(level, writer);
			return writer;
		}
		return null;
	}

	private String currTime() {
		return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
	}

	public void close() {
		try {
			Collection<BufferedWriter> list = mWriterMap.values();
			for (BufferedWriter temp : list) {
				temp.close();
				temp = null;
			}
			list.clear();
			mWriterMap.clear();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
